blob: dd5df6428f99dda2908a3125ec85170165ef8d87 [file] [log] [blame]
Javier B Perez Hernandezf7fffae2015-10-06 11:00:37 -05001/*
2 * Copyright (c) 2015 Intel Corporation.
Dirk Brandewiec9ac95a2015-06-01 11:11:39 -07003 *
David B. Kinderac74d8b2017-01-18 17:01:01 -08004 * SPDX-License-Identifier: Apache-2.0
Dirk Brandewiec9ac95a2015-06-01 11:11:39 -07005 */
6
Flavio Ceolin67ca1762018-09-14 10:43:44 -07007#ifndef ZEPHYR_INCLUDE_INIT_H_
8#define ZEPHYR_INCLUDE_INIT_H_
Dirk Brandewiec9ac95a2015-06-01 11:11:39 -07009
Andrew Boiea13fddb2015-08-04 16:37:35 -070010#include <toolchain.h>
Tomasz Bursztyka8d7bb8f2020-03-09 11:02:20 +010011#include <kernel.h>
12#include <zephyr/types.h>
Dirk Brandewiec9ac95a2015-06-01 11:11:39 -070013
Peter Mitsisa0e45682016-01-22 12:38:49 -050014#ifdef __cplusplus
15extern "C" {
16#endif
17
Dirk Brandewie92d01352015-09-25 13:02:12 -070018/*
Andrew Boie0b474ee2016-11-08 11:06:55 -080019 * System initialization levels. The PRE_KERNEL_1 and PRE_KERNEL_2 levels are
Allan Stephensa860cb72015-10-14 11:17:20 -040020 * executed in the kernel's initialization context, which uses the interrupt
Andrew Boie0b474ee2016-11-08 11:06:55 -080021 * stack. The remaining levels are executed in the kernel's main task.
Dirk Brandewieac3fdf02015-06-24 08:22:56 -070022 */
Dirk Brandewiec9ac95a2015-06-01 11:11:39 -070023
Andrew Boie0b474ee2016-11-08 11:06:55 -080024#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
Daniel Leung4e1637b2020-01-15 08:57:29 -080029#ifdef CONFIG_SMP
30#define _SYS_INIT_LEVEL_SMP 4
31#endif
32
Tomasz Bursztyka8d7bb8f2020-03-09 11:02:20 +010033struct 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 */
43struct init_entry {
Tomasz Bursztyka871c7102020-06-19 08:05:56 +020044 /** Initialization function for the init entry which will take
45 * the dev attribute as parameter. See below.
46 */
Tomasz Bursztykae18fcbb2020-04-30 20:33:38 +020047 int (*init)(const struct device *dev);
Tomasz Bursztyka871c7102020-06-19 08:05:56 +020048 /** 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 */
Tomasz Bursztykae18fcbb2020-04-30 20:33:38 +020051 const struct device *dev;
Tomasz Bursztyka8d7bb8f2020-03-09 11:02:20 +010052};
53
Spoorthy Priya Yerabolu9247e8b2020-08-25 03:11:16 -070054void z_sys_init_run_level(int32_t _level);
Tomasz Bursztyka8d7bb8f2020-03-09 11:02:20 +010055
Sebastian Bøef816c392018-03-26 15:31:06 +020056/* 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.
Andrew Boiea5b26822016-09-22 11:14:59 -070058 */
Spoorthy Priya Yerabolu9247e8b2020-08-25 03:11:16 -070059#define Z_SYS_NAME(_init_fn) _CONCAT(_CONCAT(sys_init_, _init_fn), __COUNTER__)
Andrew Boiea5b26822016-09-22 11:14:59 -070060
Andrew Boiea498d462016-09-07 14:51:32 -070061/**
Tomasz Bursztyka8d7bb8f2020-03-09 11:02:20 +010062 * @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_AND_API_INIT() instead.
71 *
Spoorthy Priya Yerabolu9247e8b2020-08-25 03:11:16 -070072 * @param _entry_name Init entry name. It is the name this instance exposes to
Tomasz Bursztyka8d7bb8f2020-03-09 11:02:20 +010073 * the system.
74 *
Spoorthy Priya Yerabolu9247e8b2020-08-25 03:11:16 -070075 * @param _init_fn Address to the init function of the entry.
Tomasz Bursztyka8d7bb8f2020-03-09 11:02:20 +010076 *
Spoorthy Priya Yerabolu9247e8b2020-08-25 03:11:16 -070077 * @param _device A device driver instance pointer or NULL
Tomasz Bursztyka8d7bb8f2020-03-09 11:02:20 +010078 *
Spoorthy Priya Yerabolu9247e8b2020-08-25 03:11:16 -070079 * @param _level The initialization level at which configuration
Peter Bigot2fe35e82020-06-10 09:37:56 -050080 * 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 */
Spoorthy Priya Yerabolu9247e8b2020-08-25 03:11:16 -070085#define Z_INIT_ENTRY_DEFINE(_entry_name, _init_fn, _device, _level, _prio) \
Peter Bigot2fe35e82020-06-10 09:37:56 -050086 static const Z_DECL_ALIGN(struct init_entry) \
Spoorthy Priya Yerabolu9247e8b2020-08-25 03:11:16 -070087 _CONCAT(__init_, _entry_name) __used \
88 __attribute__((__section__(".init_" #_level STRINGIFY(_prio)))) = { \
89 .init = (_init_fn), \
90 .dev = (_device), \
Peter Bigot2fe35e82020-06-10 09:37:56 -050091 }
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 *
Spoorthy Priya Yerabolu9247e8b2020-08-25 03:11:16 -0700102 * @param _init_fn Pointer to the boot function to run
Peter Bigot2fe35e82020-06-10 09:37:56 -0500103 *
Spoorthy Priya Yerabolu9247e8b2020-08-25 03:11:16 -0700104 * @param _level The initialization level at which configuration occurs.
Tomasz Bursztyka8d7bb8f2020-03-09 11:02:20 +0100105 * 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 *
Spoorthy Priya Yerabolu9247e8b2020-08-25 03:11:16 -0700127 * @param _prio The initialization priority of the object, relative to
Tomasz Bursztyka8d7bb8f2020-03-09 11:02:20 +0100128 * 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 */
Spoorthy Priya Yerabolu9247e8b2020-08-25 03:11:16 -0700135#define SYS_INIT(_init_fn, _level, _prio) \
136 Z_INIT_ENTRY_DEFINE(Z_SYS_NAME(_init_fn), _init_fn, NULL, _level, _prio)
amirkapld305da62016-09-01 09:01:10 +0300137
Peter Mitsisa0e45682016-01-22 12:38:49 -0500138#ifdef __cplusplus
139}
140#endif
141
Flavio Ceolin67ca1762018-09-14 10:43:44 -0700142#endif /* ZEPHYR_INCLUDE_INIT_H_ */