1 /* SPDX-License-Identifier: GPL-2.0-only */
8 /* Only declare main() when in ramstage. */
10 #include <main_decl.h>
14 * The boot state machine provides a mechanism for calls to be made through-
15 * out the main boot process. The boot process is separated into discrete
16 * states. Upon a state's entry and exit and callbacks can be made. For
34 * Below is the current flow from top to bottom:
52 * BS_OS_RESUME_CHECK -------- BS_OS_RESUME
54 * BS_WRITE_TABLES os handoff
62 * Brief description of states:
63 * BS_PRE_DEVICE - before any device tree actions take place
64 * BS_DEV_INIT_CHIPS - init all chips in device tree
65 * BS_DEV_ENUMERATE - device tree probing
66 * BS_DEV_RESOURCES - device tree resource allocation and assignment
67 * BS_DEV_ENABLE - device tree enabling/disabling of devices
68 * BS_DEV_INIT - device tree device initialization
69 * BS_POST_DEVICE - all device tree actions performed
70 * BS_OS_RESUME_CHECK - check for OS resume
71 * BS_OS_RESUME - resume to OS
72 * BS_WRITE_TABLES - write coreboot tables
73 * BS_PAYLOAD_LOAD - Load payload into memory
74 * BS_PAYLOAD_BOOT - Boot to payload
92 /* The boot_state_sequence_t describes when a callback is to be made. It is
93 * called either before a state is entered or when a state is exited. */
97 } boot_state_sequence_t
;
99 struct boot_state_callback
{
101 void (*callback
)(void *arg
);
102 /* For use internal to the boot state machine. */
103 struct boot_state_callback
*next
;
104 #if CONFIG(DEBUG_BOOT_STATE)
105 const char *location
;
109 static inline const char *bscb_location(const struct boot_state_callback
*bscb
)
111 #if CONFIG(DEBUG_BOOT_STATE)
112 return bscb
->location
;
114 return dead_code_t(const char *);
118 #if CONFIG(DEBUG_BOOT_STATE)
119 #define BOOT_STATE_CALLBACK_LOC __FILE__ ":" STRINGIFY(__LINE__)
120 #define BOOT_STATE_CALLBACK_INIT_DEBUG .location = BOOT_STATE_CALLBACK_LOC,
121 #define INIT_BOOT_STATE_CALLBACK_DEBUG(bscb_) \
123 bscb_->location = BOOT_STATE_CALLBACK_LOC; \
126 #define BOOT_STATE_CALLBACK_INIT_DEBUG
127 #define INIT_BOOT_STATE_CALLBACK_DEBUG(bscb_)
130 #define BOOT_STATE_CALLBACK_INIT(func_, arg_) \
135 BOOT_STATE_CALLBACK_INIT_DEBUG \
138 #define BOOT_STATE_CALLBACK(name_, func_, arg_) \
139 struct boot_state_callback name_ = BOOT_STATE_CALLBACK_INIT(func_, arg_)
141 /* Initialize an allocated boot_state_callback. */
142 #define INIT_BOOT_STATE_CALLBACK(bscb_, func_, arg_) \
144 INIT_BOOT_STATE_CALLBACK_DEBUG(bscb_) \
145 bscb_->callback = func_; \
149 /* The following 2 functions schedule a callback to be called on entry/exit
150 * to a given state. Note that there are no ordering guarantees between the
151 * individual callbacks on a given state. 0 is returned on success < 0 on
153 int boot_state_sched_on_entry(struct boot_state_callback
*bscb
,
155 int boot_state_sched_on_exit(struct boot_state_callback
*bscb
,
157 /* Schedule an array of entries of size num. */
158 struct boot_state_init_entry
;
159 void boot_state_sched_entries(struct boot_state_init_entry
*entries
,
162 /* Block/Unblock the (state, seq) pair from transitioning. Returns 0 on
163 * success < 0 when the phase of the (state,seq) has already ran. */
164 int boot_state_block(boot_state_t state
, boot_state_sequence_t seq
);
165 int boot_state_unblock(boot_state_t state
, boot_state_sequence_t seq
);
167 /* In order to schedule boot state callbacks at compile-time specify the
168 * entries in an array using the BOOT_STATE_INIT_ENTRIES and
169 * BOOT_STATE_INIT_ENTRY macros below. */
170 struct boot_state_init_entry
{
172 boot_state_sequence_t when
;
173 struct boot_state_callback bscb
;
177 #define BOOT_STATE_INIT_ATTR __attribute__((used, section(".bs_init")))
179 #define BOOT_STATE_INIT_ATTR __attribute__((unused))
182 #define BOOT_STATE_INIT_ENTRY(state_, when_, func_, arg_) \
183 static struct boot_state_init_entry func_ ##_## state_ ##_## when_ = \
187 .bscb = BOOT_STATE_CALLBACK_INIT(func_, arg_), \
189 static struct boot_state_init_entry * \
190 bsie_ ## func_ ##_## state_ ##_## when_ BOOT_STATE_INIT_ATTR = \
191 &func_ ##_## state_ ##_## when_;
193 /* Hook per arch when coreboot is exiting to payload or ACPI OS resume. It's
194 * the very last thing done before the transition. */
195 void arch_bootstate_coreboot_exit(void);
197 #endif /* BOOTSTATE_H */