mb/{asrock,intel,purism}: Copy channel arrays separately
[coreboot.git] / src / include / bootstate.h
blob26038c610173e852517ad75ef80e622436a0b09e
1 /*
2 * This file is part of the coreboot project.
4 * Copyright (C) 2013 Google, Inc.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 #ifndef BOOTSTATE_H
16 #define BOOTSTATE_H
18 #include <string.h>
19 #include <stdlib.h>
20 #include <stddef.h>
21 #include <stdint.h>
22 /* Only declare main() when in ramstage. */
23 #if ENV_RAMSTAGE
24 #include <main_decl.h>
25 #endif
28 * The boot state machine provides a mechanism for calls to be made through-
29 * out the main boot process. The boot process is separated into discrete
30 * states. Upon a state's entry and exit and callbacks can be made. For
31 * example:
33 * Enter State
34 * +
35 * |
36 * V
37 * +-----------------+
38 * | Entry callbacks |
39 * +-----------------+
40 * | State Actions |
41 * +-----------------+
42 * | Exit callbacks |
43 * +-------+---------+
44 * |
45 * V
46 * Next State
48 * Below is the current flow from top to bottom:
50 * start
51 * |
52 * BS_PRE_DEVICE
53 * |
54 * BS_DEV_INIT_CHIPS
55 * |
56 * BS_DEV_ENUMERATE
57 * |
58 * BS_DEV_RESOURCES
59 * |
60 * BS_DEV_ENABLE
61 * |
62 * BS_DEV_INIT
63 * |
64 * BS_POST_DEVICE
65 * |
66 * BS_OS_RESUME_CHECK -------- BS_OS_RESUME
67 * | |
68 * BS_WRITE_TABLES os handoff
69 * |
70 * BS_PAYLOAD_LOAD
71 * |
72 * BS_PAYLOAD_BOOT
73 * |
74 * payload run
76 * Brief description of states:
77 * BS_PRE_DEVICE - before any device tree actions take place
78 * BS_DEV_INIT_CHIPS - init all chips in device tree
79 * BS_DEV_ENUMERATE - device tree probing
80 * BS_DEV_RESOURCES - device tree resource allocation and assignment
81 * BS_DEV_ENABLE - device tree enabling/disabling of devices
82 * BS_DEV_INIT - device tree device initialization
83 * BS_POST_DEVICE - all device tree actions performed
84 * BS_OS_RESUME_CHECK - check for OS resume
85 * BS_OS_RESUME - resume to OS
86 * BS_WRITE_TABLES - write coreboot tables
87 * BS_PAYLOAD_LOAD - Load payload into memory
88 * BS_PAYLOAD_BOOT - Boot to payload
91 typedef enum {
92 BS_PRE_DEVICE,
93 BS_DEV_INIT_CHIPS,
94 BS_DEV_ENUMERATE,
95 BS_DEV_RESOURCES,
96 BS_DEV_ENABLE,
97 BS_DEV_INIT,
98 BS_POST_DEVICE,
99 BS_OS_RESUME_CHECK,
100 BS_OS_RESUME,
101 BS_WRITE_TABLES,
102 BS_PAYLOAD_LOAD,
103 BS_PAYLOAD_BOOT,
104 } boot_state_t;
106 /* The boot_state_sequence_t describes when a callback is to be made. It is
107 * called either before a state is entered or when a state is exited. */
108 typedef enum {
109 BS_ON_ENTRY,
110 BS_ON_EXIT
111 } boot_state_sequence_t;
113 struct boot_state_callback {
114 void *arg;
115 void (*callback)(void *arg);
116 /* For use internal to the boot state machine. */
117 struct boot_state_callback *next;
118 #if CONFIG(DEBUG_BOOT_STATE)
119 const char *location;
120 #endif
123 #if CONFIG(DEBUG_BOOT_STATE)
124 #define BOOT_STATE_CALLBACK_LOC __FILE__ ":" STRINGIFY(__LINE__)
125 #define BOOT_STATE_CALLBACK_INIT_DEBUG .location = BOOT_STATE_CALLBACK_LOC,
126 #define INIT_BOOT_STATE_CALLBACK_DEBUG(bscb_) \
127 do { \
128 bscb_->location = BOOT_STATE_CALLBACK_LOC; \
129 } while (0)
130 #else
131 #define BOOT_STATE_CALLBACK_INIT_DEBUG
132 #define INIT_BOOT_STATE_CALLBACK_DEBUG(bscb_)
133 #endif
135 #define BOOT_STATE_CALLBACK_INIT(func_, arg_) \
137 .arg = arg_, \
138 .callback = func_, \
139 .next = NULL, \
140 BOOT_STATE_CALLBACK_INIT_DEBUG \
143 #define BOOT_STATE_CALLBACK(name_, func_, arg_) \
144 struct boot_state_callback name_ = BOOT_STATE_CALLBACK_INIT(func_, arg_)
146 /* Initialize an allocated boot_state_callback. */
147 #define INIT_BOOT_STATE_CALLBACK(bscb_, func_, arg_) \
148 do { \
149 INIT_BOOT_STATE_CALLBACK_DEBUG(bscb_) \
150 bscb_->callback = func_; \
151 bscb_->arg = arg_ \
152 } while (0)
154 /* The following 2 functions schedule a callback to be called on entry/exit
155 * to a given state. Note that there are no ordering guarantees between the
156 * individual callbacks on a given state. 0 is returned on success < 0 on
157 * error. */
158 int boot_state_sched_on_entry(struct boot_state_callback *bscb,
159 boot_state_t state);
160 int boot_state_sched_on_exit(struct boot_state_callback *bscb,
161 boot_state_t state);
162 /* Schedule an array of entries of size num. */
163 struct boot_state_init_entry;
164 void boot_state_sched_entries(struct boot_state_init_entry *entries,
165 size_t num);
167 /* Block/Unblock the (state, seq) pair from transitioning. Returns 0 on
168 * success < 0 when the phase of the (state,seq) has already ran. */
169 int boot_state_block(boot_state_t state, boot_state_sequence_t seq);
170 int boot_state_unblock(boot_state_t state, boot_state_sequence_t seq);
171 /* Block/Unblock current state phase from transitioning. */
172 void boot_state_current_block(void);
173 void boot_state_current_unblock(void);
175 /* In order to schedule boot state callbacks at compile-time specify the
176 * entries in an array using the BOOT_STATE_INIT_ENTRIES and
177 * BOOT_STATE_INIT_ENTRY macros below. */
178 struct boot_state_init_entry {
179 boot_state_t state;
180 boot_state_sequence_t when;
181 struct boot_state_callback bscb;
184 #if ENV_RAMSTAGE
185 #define BOOT_STATE_INIT_ATTR __attribute__((used, section(".bs_init")))
186 #else
187 #define BOOT_STATE_INIT_ATTR __attribute__((unused))
188 #endif
190 #define BOOT_STATE_INIT_ENTRY(state_, when_, func_, arg_) \
191 static struct boot_state_init_entry func_ ##_## state_ ##_## when_ = \
193 .state = state_, \
194 .when = when_, \
195 .bscb = BOOT_STATE_CALLBACK_INIT(func_, arg_), \
196 }; \
197 static struct boot_state_init_entry * \
198 bsie_ ## func_ ##_## state_ ##_## when_ BOOT_STATE_INIT_ATTR = \
199 &func_ ##_## state_ ##_## when_;
201 /* Hook per arch when coreboot is exiting to payload or ACPI OS resume. It's
202 * the very last thing done before the transition. */
203 void arch_bootstate_coreboot_exit(void);
205 #endif /* BOOTSTATE_H */