1 /*
2  * Copyright (c) 2015 Intel Corporation.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef ZEPHYR_INCLUDE_INIT_H_
8 #define ZEPHYR_INCLUDE_INIT_H_
9 
10 #include <toolchain.h>
11 #include <kernel.h>
12 #include <zephyr/types.h>
13 
14 #ifdef __cplusplus
15 extern "C" {
16 #endif
17 
18 /*
19  * System initialization levels. The PRE_KERNEL_1 and PRE_KERNEL_2 levels are
20  * executed in the kernel's initialization context, which uses the interrupt
21  * stack. The remaining levels are executed in the kernel's main task.
22  */
23 
24 #define _SYS_INIT_LEVEL_PRE_KERNEL_1	0
25 #define _SYS_INIT_LEVEL_PRE_KERNEL_2	1
26 #define _SYS_INIT_LEVEL_POST_KERNEL	2
27 #define _SYS_INIT_LEVEL_APPLICATION	3
28 
29 #ifdef CONFIG_SMP
30 #define _SYS_INIT_LEVEL_SMP		4
31 #endif
32 
33 struct device;
34 
35 /**
36  * @brief Static init entry structure for each device driver or services
37  *
38  * @param init init function for the init entry which will take the dev
39  * attribute as parameter. See below.
40  * @param dev pointer to a device driver instance structure. Can be NULL
41  * if the init entry is not used for a device driver but a service.
42  */
43 struct init_entry {
44 	/** Initialization function for the init entry which will take
45 	 * the dev attribute as parameter. See below.
46 	 */
47 	int (*init)(const struct device *dev);
48 	/** Pointer to a device driver instance structure. Can be NULL
49 	 * if the init entry is not used for a device driver but a services.
50 	 */
51 	const struct device *dev;
52 };
53 
54 void z_sys_init_run_level(int32_t level);
55 
56 /* A counter is used to avoid issues when two or more system devices
57  * are declared in the same C file with the same init function.
58  */
59 #define Z_SYS_NAME(_init_fn) _CONCAT(_CONCAT(sys_init_, _init_fn), __COUNTER__)
60 
61 /**
62  * @def Z_INIT_ENTRY_DEFINE
63  *
64  * @brief Create an init entry object and set it up for boot time initialization
65  *
66  * @details This macro defines an init entry object that will be automatically
67  * configured by the kernel during system initialization. Note that
68  * init entries will not be accessible from user mode. Also this macro should
69  * not be used directly, use relevant macro such as SYS_INIT() or
70  * DEVICE_DEFINE() instead.
71  *
72  * @param _entry_name Init entry name. It is the name this instance exposes to
73  * the system.
74  *
75  * @param _init_fn Address to the init function of the entry.
76  *
77  * @param _device A device driver instance pointer or NULL
78  *
79  * @param _level The initialization level at which configuration
80  * occurs.  See SYS_INIT().
81  *
82  * @param prio The initialization priority of the object, relative to
83  * other objects of the same initialization level. See SYS_INIT().
84  */
85 #define Z_INIT_ENTRY_DEFINE(_entry_name, _init_fn, _device, _level, _prio)	\
86 	static const Z_DECL_ALIGN(struct init_entry)			\
87 		_CONCAT(__init_, _entry_name) __used			\
88 	__attribute__((__section__(".z_init_" #_level STRINGIFY(_prio)"_"))) = { \
89 		.init = (_init_fn),					\
90 		.dev = (_device),					\
91 	}
92 
93 /**
94  * @def SYS_INIT
95  *
96  * @ingroup device_model
97  *
98  * @brief Run an initialization function at boot at specified priority
99  *
100  * @details This macro lets you run a function at system boot.
101  *
102  * @param _init_fn Pointer to the boot function to run
103  *
104  * @param _level The initialization level at which configuration occurs.
105  * Must be one of the following symbols, which are listed in the order
106  * they are performed by the kernel:
107  * \n
108  * \li PRE_KERNEL_1: Used for initialization objects that have no dependencies,
109  * such as those that rely solely on hardware present in the processor/SOC.
110  * These objects cannot use any kernel services during configuration, since
111  * they are not yet available.
112  * \n
113  * \li PRE_KERNEL_2: Used for initialization objects that rely on objects
114  * initialized as part of the PRE_KERNEL_1 level. These objects cannot use any
115  * kernel services during configuration, since they are not yet available.
116  * \n
117  * \li POST_KERNEL: Used for initialization objects that require kernel services
118  * during configuration.
119  * \n
120  * \li POST_KERNEL_SMP: Used for initialization objects that require kernel
121  * services during configuration after SMP initialization.
122  * \n
123  * \li APPLICATION: Used for application components (i.e. non-kernel components)
124  * that need automatic configuration. These objects can use all services
125  * provided by the kernel during configuration.
126  *
127  * @param _prio The initialization priority of the object, relative to
128  * other objects of the same initialization level. Specified as an integer
129  * value in the range 0 to 99; lower values indicate earlier initialization.
130  * Must be a decimal integer literal without leading zeroes or sign (e.g. 32),
131  * or an equivalent symbolic name (e.g. \#define MY_INIT_PRIO 32); symbolic
132  * expressions are *not* permitted
133  * (e.g. CONFIG_KERNEL_INIT_PRIORITY_DEFAULT + 5).
134  */
135 #define SYS_INIT(_init_fn, _level, _prio)					\
136 	Z_INIT_ENTRY_DEFINE(Z_SYS_NAME(_init_fn), _init_fn, NULL, _level, _prio)
137 
138 #ifdef __cplusplus
139 }
140 #endif
141 
142 #endif /* ZEPHYR_INCLUDE_INIT_H_ */
143