blob: 202acf7d4e913ec1b1bb3d0c6061ad1acec08153 [file] [log] [blame]
Aaron Durbin7e35efa2013-04-24 15:14:01 -05001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2013 Google, Inc.
5 *
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.
9 *
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.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19#ifndef BOOTSTATE_H
20#define BOOTSTATE_H
21
Patrick Georgi5c715ac2014-08-14 19:23:41 +020022#if !defined(__SMM__) && !defined(__PRE_RAM__)
23
Aaron Durbin7e35efa2013-04-24 15:14:01 -050024#include <string.h>
25
26/* Control debugging of the boot state machine. */
27#define BOOT_STATE_DEBUG 0
28
29/*
30 * The boot state machine provides a mechanism for calls to be made through-
31 * out the main boot process. The boot process is separated into discrete
32 * states. Upon a state's entry and exit and callbacks can be made. For
33 * example:
34 *
35 * Enter State
36 * +
37 * |
38 * V
39 * +-----------------+
40 * | Entry callbacks |
41 * +-----------------+
42 * | State Actions |
43 * +-----------------+
44 * | Exit callbacks |
45 * +-------+---------+
46 * |
47 * V
48 * Next State
49 *
50 * Below is the current flow from top to bottom:
51 *
52 * start
53 * |
54 * BS_PRE_DEVICE
55 * |
56 * BS_DEV_INIT_CHIPS
57 * |
58 * BS_DEV_ENUMERATE
59 * |
60 * BS_DEV_RESOURCES
61 * |
62 * BS_DEV_ENABLE
63 * |
64 * BS_DEV_INIT
65 * |
66 * BS_POST_DEVICE
67 * |
68 * BS_OS_RESUME_CHECK -------- BS_OS_RESUME
69 * | |
70 * BS_WRITE_TABLES os handoff
71 * |
72 * BS_PAYLOAD_LOAD
73 * |
74 * BS_PAYLOAD_BOOT
75 * |
76 * payload run
77 *
78 * Brief description of states:
79 * BS_PRE_DEVICE - before any device tree actions take place
80 * BS_DEV_INIT_CHIPS - init all chips in device tree
81 * BS_DEV_ENUMERATE - device tree probing
82 * BS_DEV_RESOURCES - device tree resource allocation and assignment
83 * BS_DEV_ENABLE - device tree enabling/disabling of devices
84 * BS_DEV_INIT - device tree device initialization
85 * BS_POST_DEVICE - all device tree actions performed
86 * BS_OS_RESUME_CHECK - check for OS resume
87 * BS_OS_RESUME - resume to OS
88 * BS_WRITE_TABLES - write coreboot tables
89 * BS_PAYLOAD_LOAD - Load payload into memory
90 * BS_PAYLOAD_BOOT - Boot to payload
91 */
92
93typedef enum {
94 BS_PRE_DEVICE,
95 BS_DEV_INIT_CHIPS,
96 BS_DEV_ENUMERATE,
97 BS_DEV_RESOURCES,
98 BS_DEV_ENABLE,
99 BS_DEV_INIT,
100 BS_POST_DEVICE,
Aaron Durbin0a6c20a2013-04-24 22:33:08 -0500101 BS_OS_RESUME_CHECK,
Aaron Durbin7e35efa2013-04-24 15:14:01 -0500102 BS_OS_RESUME,
103 BS_WRITE_TABLES,
104 BS_PAYLOAD_LOAD,
105 BS_PAYLOAD_BOOT,
106} boot_state_t;
107
108/* The boot_state_sequence_t describes when a callback is to be made. It is
109 * called either before a state is entered or when a state is exited. */
110typedef enum {
111 BS_ON_ENTRY,
112 BS_ON_EXIT
113} boot_state_sequence_t;
114
115struct boot_state_callback {
116 void *arg;
117 void (*callback)(void *arg);
118 /* For use internal to the boot state machine. */
119 struct boot_state_callback *next;
120#if BOOT_STATE_DEBUG
121 const char *location;
122#endif
123};
124
125#if BOOT_STATE_DEBUG
126#define BOOT_STATE_CALLBACK_LOC __FILE__ ":" STRINGIFY(__LINE__)
127#define BOOT_STATE_CALLBACK_INIT_DEBUG .location = BOOT_STATE_CALLBACK_LOC,
128#define INIT_BOOT_STATE_CALLBACK_DEBUG(bscb_) \
129 bscb_->location = BOOT_STATE_CALLBACK_LOC;
130#else
131#define BOOT_STATE_CALLBACK_INIT_DEBUG
132#define INIT_BOOT_STATE_CALLBACK_DEBUG(bscb_)
133#endif
134
135#define BOOT_STATE_CALLBACK_INIT(func_, arg_) \
136 { \
137 .arg = arg_, \
138 .callback = func_, \
139 .next = NULL, \
140 BOOT_STATE_CALLBACK_INIT_DEBUG \
141 }
142
143#define BOOT_STATE_CALLBACK(name_, func_, arg_) \
144 struct boot_state_callback name_ = BOOT_STATE_CALLBACK_INIT(func_, arg_)
145
146/* Initialize an allocated boot_state_callback. */
147#define INIT_BOOT_STATE_CALLBACK(bscb_, func_, arg_) \
148 INIT_BOOT_STATE_CALLBACK_DEBUG(bscb_) \
149 bscb_->callback = func_; \
150 bscb_->arg = arg_
151
152/* The following 2 functions schedule a callback to be called on entry/exit
Martin Roth0cb07e32013-07-09 21:46:01 -0600153 * to a given state. Note that there are no ordering guarantees between the
Aaron Durbin7e35efa2013-04-24 15:14:01 -0500154 * individual callbacks on a given state. 0 is returned on success < 0 on
155 * error. */
156int boot_state_sched_on_entry(struct boot_state_callback *bscb,
157 boot_state_t state);
158int boot_state_sched_on_exit(struct boot_state_callback *bscb,
159 boot_state_t state);
160
Aaron Durbin0748d302013-05-06 10:50:19 -0500161/* Block/Unblock the (state, seq) pair from transitioning. Returns 0 on
162 * success < 0 when the phase of the (state,seq) has already ran. */
163int boot_state_block(boot_state_t state, boot_state_sequence_t seq);
164int boot_state_unblock(boot_state_t state, boot_state_sequence_t seq);
165/* Block/Unblock current state phase from transitioning. */
166void boot_state_current_block(void);
167void boot_state_current_unblock(void);
168
Aaron Durbin7e35efa2013-04-24 15:14:01 -0500169/* Entry into the boot state machine. */
Stefan Reinauer6adef082013-05-09 16:30:06 -0700170void main(void);
Aaron Durbin7e35efa2013-04-24 15:14:01 -0500171
Aaron Durbina4feddf2013-04-24 16:12:52 -0500172/* In order to schedule boot state callbacks at compile-time specify the
173 * entries in an array using the BOOT_STATE_INIT_ENTRIES and
174 * BOOT_STATE_INIT_ENTRY macros below. */
175struct boot_state_init_entry {
176 boot_state_t state;
177 boot_state_sequence_t when;
178 struct boot_state_callback bscb;
179};
180
181#define BOOT_STATE_INIT_ATTR __attribute__ ((used,section (".bs_init")))
182
183#define BOOT_STATE_INIT_ENTRIES(name_) \
184 static struct boot_state_init_entry name_[] BOOT_STATE_INIT_ATTR
185
186#define BOOT_STATE_INIT_ENTRY(state_, when_, func_, arg_) \
187 { \
188 .state = state_, \
189 .when = when_, \
190 .bscb = BOOT_STATE_CALLBACK_INIT(func_, arg_), \
191 }
192
Patrick Georgi5c715ac2014-08-14 19:23:41 +0200193#endif
Aaron Durbin7e35efa2013-04-24 15:14:01 -0500194#endif /* BOOTSTATE_H */